package native

import "jvmgo/ch09/rtda"

//以Frame为参数，返回void，这里并不表明此jvm对本地方法的实现，只支持不返回值的本地方法
//因为本地方法的返回值，可以直接通过操作OperandStack的方式来达成，见native/java/lang/Object里面的hashCode实现
type NativeMethod func(frame *rtda.Frame)

//map集合用来注册所有的本地方法，键为一个go语言字符串，值为NativeMethod类型。
var registry = map[string]NativeMethod{}

func emptyNativeMethod(frame *rtda.Frame) {
	// do nothing
}

func Register(className, methodName, methodDescriptor string, method NativeMethod) {
	key := className + "~" + methodName + "~" + methodDescriptor
	registry[key] = method
}

func FindNativeMethod(className, methodName, methodDescriptor string) NativeMethod {
	key := className + "~" + methodName + "~" + methodDescriptor
	if method, ok := registry[key]; ok {
		return method
	}
	//java.lang.Object类等类是靠registerNatives方法来注册本地方法的，这里统一用上面的Register方法来实现本地方法注册的功能
	//所以碰到registerNatives，直接什么也不干（见上面的emptyNativeMethod方法实现）
	if methodDescriptor == "()V" && methodName == "registerNatives" {
		return emptyNativeMethod
	}
	return nil
}
